#include <iostream>
#include <thread>
#include <vector>

#include "./Singleton.h"

void create(char c)
{
	char* ch = dpt::LazySingleton<char>::getInstance();
	int* in1 = dpt::MultipleSingleton<int, 1>::getInstance();
	static std::mutex mtx;
	std::lock_guard<std::mutex> lock(mtx);
	*ch = c;
	std::cout << (*ch) << std::endl;
	*in1 = int(c);
	std::cout << (*in1) << std::endl;
}

int main()
{
	int* a = nullptr;
	dpt::HungrySingleton<int> hs;
	dpt::HungrySingleton<int> hs2;
	dpt::MultipleSingleton<int, 1> ms;
	dpt::MultipleSingleton<int, 1> ms2;
	dpt::MultipleSingleton<int, 2> ms3;
	a = hs.getInstance();
	hs.destroyInstance();
	try
	{
		a = hs2.getInstance();
	}
	catch (const std::logic_error& e)
	{
		std::cout << e.what() << std::endl;
	}
	char* ch = nullptr;
	char* ch2 = nullptr;
	int* in1 = nullptr;
	int* in2 = nullptr;
	int* in3 = nullptr;
	std::vector<std::thread> vt;
	char newch = 'a';
	for (int i = 0; i < 5; i++)
	{
		vt.emplace_back(std::thread(create, newch));
		newch++;
	}
	for (auto& t : vt)
	{
		t.join();
	}
	dpt::LazySingleton<char> ls;
	dpt::LazySingleton<char> ls2;
	ch = ls.getInstance();
	in1 = ms.getInstance();
	*in1 = 6174;
	*ch = 'c';
	std::cout << (*ch) << std::endl;
	std::cout << (*in1) << std::endl;
	vt.clear();
	for (int i = 0; i < 5; i++)
	{
		vt.emplace_back(std::thread(create, newch));
		newch++;
	}
	for (auto& t : vt)
	{
		t.join();
	}
	ch2 = ls2.getInstance();
	in2 = ms2.getInstance();
	in3 = ms3.getInstance();
	return 0;
}